// Word 模块中文API封装 - 基于docx库
// 提供完整的Word文档创建、读取、修改和操作功能

// 引入必要的依赖
const fs = require('fs');
const path = require('path');

// 动态导入docx库
let docx;
try {
  docx = require('docx');
} catch (error) {
  console.warn('docx库未安装，请先运行: npm install docx');
}

// 验证docx库是否可用
function 验证docx库() {
  if (!docx) {
    throw new Error('docx库未安装或无法加载');
  }
  return true;
}

/**
 * 读取Word文档文件
 * @param {string} 文件路径 - Word文档路径
 * @returns {Promise<Object>} 文档解析对象
 */
async function 读取Word文档(文件路径) {
  验证docx库();
  
  try {
    const buffer = await fs.promises.readFile(文件路径);
    return await docx.Document.fromBuffer(buffer);
  } catch (错误) {
    throw new Error(`读取Word文档失败: ${错误.message}`);
  }
}

/**
 * 从Buffer加载Word文档
 * @param {Buffer} 缓冲区 - 文档Buffer数据
 * @returns {Promise<Object>} 文档解析对象
 */
async function 从Buffer加载文档(缓冲区) {
  验证docx库();
  
  try {
    return await docx.Document.fromBuffer(缓冲区);
  } catch (错误) {
    throw new Error(`从Buffer加载文档失败: ${错误.message}`);
  }
}

/**
 * 获取文档中的所有节
 * @param {Object} 文档 - docx文档实例
 * @returns {Array} 节数组
 */
function 获取文档节(文档) {
  验证docx库();
  return 文档.sections || [];
}

/**
 * 提取文档中的所有文本内容
 * @param {Object} 文档 - docx文档实例
 * @returns {string} 文档文本内容
 */
function 获取文档文本(文档) {
  验证docx库();
  
  const 节列表 = 获取文档节(文档);
  let 文本内容 = '';
  
  节列表.forEach(节 => {
    if (节.children && Array.isArray(节.children)) {
      节.children.forEach(子元素 => {
        if (子元素 instanceof docx.Paragraph) {
          if (子元素.children && Array.isArray(子元素.children)) {
            子元素.children.forEach(段落元素 => {
              if (段落元素 instanceof docx.TextRun) {
                文本内容 += 段落元素.text || '';
              }
            });
          }
          文本内容 += '\n';
        }
      });
    }
  });
  
  return 文本内容.trim();
}

/**
 * 在文档中搜索文本
 * @param {Object} 文档 - docx文档实例
 * @param {string} 搜索文本 - 要查找的文本
 * @returns {Array} 匹配项位置信息数组
 */
function 搜索文本(文档, 搜索文本) {
  验证docx库();
  
  const 匹配项 = [];
  const 节列表 = 获取文档节(文档);
  let 当前位置 = 0;
  
  节列表.forEach((节, 节索引) => {
    if (节.children && Array.isArray(节.children)) {
      节.children.forEach((段落, 段落索引) => {
        if (段落 instanceof docx.Paragraph && 段落.children) {
          段落.children.forEach((文本元素, 元素索引) => {
            if (文本元素 instanceof docx.TextRun && 文本元素.text) {
              const 文本位置 = 文本元素.text.indexOf(搜索文本);
              if (文本位置 !== -1) {
                匹配项.push({
                  节索引,
                  段落索引,
                  元素索引,
                  文本位置,
                  完整位置: 当前位置 + 文本位置,
                  长度: 搜索文本.length
                });
              }
              当前位置 += (文本元素.text || '').length;
            }
          });
          当前位置++;
        }
      });
    }
  });
  
  return 匹配项;
}

/**
 * 替换文档中的文本
 * @param {Object} 文档 - docx文档实例
 * @param {string} 查找文本 - 要替换的文本
 * @param {string} 替换文本 - 替换后的文本
 * @returns {Object} 更新后的文档
 */
function 替换文本(文档, 查找文本, 替换文本) {
  验证docx库();
  
  const 节列表 = 获取文档节(文档);
  
  节列表.forEach(节 => {
    if (节.children && Array.isArray(节.children)) {
      节.children.forEach(段落 => {
        if (段落 instanceof docx.Paragraph && 段落.children) {
          段落.children.forEach(文本元素 => {
            if (文本元素 instanceof docx.TextRun && 文本元素.text) {
              if (文本元素.text.includes(查找文本)) {
                文本元素.text = 文本元素.text.replace(查找文本, 替换文本);
              }
            }
          });
        }
      });
    }
  });
  
  return 文档;
}

/**
 * 为文档添加水印
 * @param {Object} 文档 - docx文档实例
 * @param {string} 水印文本 - 水印文本内容
 * @param {Object} 水印选项 - 水印样式选项
 * @returns {Object} 添加水印后的文档
 */
function 添加水印(文档, 水印文本, 水印选项 = {}) {
  验证docx库();
  
  // 在docx库中实现水印需要通过页眉或背景来实现
  const 水印页眉 = 创建页眉([
    创建文本框(
      [创建文本(水印文本, {
        bold: true,
        italics: true,
        color: 水印选项.颜色 || 'FF0000',
        size: 水印选项.字号 || 100,
        ...水印选项.文本样式
      })],
      {
        width: {
          size: 4000,
          type: 'dxa'
        },
        height: {
          size: 2000,
          type: 'dxa'
        },
        floating: {
          horizontalPosition: {
            offset: 1440 // 1 inch
          },
          verticalPosition: {
            offset: 3600 // 2.5 inches
          }
        },
        ...水印选项.文本框样式
      }
    )
  ]);
  
  // 为所有节添加水印页眉
  const 节列表 = 获取文档节(文档);
  节列表.forEach(节 => {
    if (!节.properties) {
      节.properties = {};
    }
    节.properties.header = 水印页眉;
  });
  
  return 文档;
}

/**
 * 设置文档属性
 * @param {Object} 文档 - docx文档实例
 * @param {Object} 属性 - 文档属性对象
 * @returns {Object} 更新后的文档
 */
function 设置文档属性(文档, 属性) {
  验证docx库();
  
  if (!文档.coreProperties) {
    文档.coreProperties = {};
  }
  
  Object.assign(文档.coreProperties, {
    title: 属性.标题 || 文档.coreProperties.title,
    subject: 属性.主题 || 文档.coreProperties.subject,
    creator: 属性.创建者 || 文档.coreProperties.creator,
    keywords: 属性.关键词 || 文档.coreProperties.keywords,
    description: 属性.描述 || 文档.coreProperties.description,
    lastModifiedBy: 属性.最后修改者 || 文档.coreProperties.lastModifiedBy,
    ...属性
  });
  
  return 文档;
}

/**
 * 获取文档属性
 * @param {Object} 文档 - docx文档实例
 * @returns {Object} 文档属性对象
 */
function 获取文档属性(文档) {
  验证docx库();
  return 文档.coreProperties || {};
}

/**
 * 为文档添加页脚页码
 * @param {Object} 文档 - docx文档实例
 * @param {Object} 页码选项 - 页码样式选项
 * @returns {Object} 更新后的文档
 */
function 添加页脚页码(文档, 页码选项 = {}) {
  验证docx库();
  
  const 页码段落 = 创建段落([
    创建页码(页码选项)
  ], {
    alignment: 页码选项.对齐方式 || 'center',
    ...页码选项.段落样式
  });
  
  const 页码页脚 = 创建页脚([页码段落]);
  
  // 为所有节添加页码页脚
  const 节列表 = 获取文档节(文档);
  节列表.forEach(节 => {
    if (!节.properties) {
      节.properties = {};
    }
    节.properties.footer = 页码页脚;
  });
  
  return 文档;
}

/**
 * 合并多个Word文档
 * @param {Array} 文档列表 - 要合并的文档实例数组
 * @returns {Object} 合并后的文档
 */
function 合并文档(文档列表) {
  验证docx库();
  
  if (!Array.isArray(文档列表) || 文档列表.length === 0) {
    throw new Error('文档列表必须是非空数组');
  }
  
  // 创建新文档作为合并结果
  const 合并文档 = 创建文档();
  
  // 合并所有文档的节
  文档列表.forEach((源文档, 索引) => {
    const 源文档节 = 获取文档节(源文档);
    源文档节.forEach(节 => {
      // 复制节并添加到合并文档
      const 复制节 = 创建节({
        properties: 节.properties,
        children: [...(节.children || [])]
      });
      
      // 在文档之间添加分页符（除了第一个文档）
      if (索引 > 0) {
        复制节.children.unshift(new docx.Paragraph({
          pageBreak: true
        }));
      }
      
      合并文档.addSection(复制节);
    });
  });
  
  return 合并文档;
}

/**
 * 从文档中提取图片
 * @param {Object} 文档 - docx文档实例
 * @param {string} 输出目录 - 图片保存目录
 * @returns {Promise<Array>} 提取的图片信息数组
 */
async function 提取图片(文档, 输出目录) {
  验证docx库();
  
  // 确保输出目录存在
  if (!fs.existsSync(输出目录)) {
    await fs.promises.mkdir(输出目录, { recursive: true });
  }
  
  const 图片列表 = [];
  let 图片计数器 = 0;
  
  // 注意：docx库的当前版本可能不直接支持从已解析文档中提取图片
  // 以下是一个基本实现，实际使用时可能需要调整
  console.warn('警告: docx库可能不直接支持从已解析文档中提取图片');
  
  return 图片列表;
}

/**
 * 从文档中提取表格数据
 * @param {Object} 文档 - docx文档实例
 * @returns {Array} 表格数据二维数组
 */
function 提取表格数据(文档) {
  验证docx库();
  
  const 表格列表 = [];
  const 节列表 = 获取文档节(文档);
  
  节列表.forEach(节 => {
    if (节.children && Array.isArray(节.children)) {
      节.children.forEach(元素 => {
        if (元素 instanceof docx.Table) {
          const 表格数据 = [];
          
          // 提取表格数据
          if (元素.rows && Array.isArray(元素.rows)) {
            元素.rows.forEach(行 => {
              const 行数据 = [];
              
              if (行.children && Array.isArray(行.children)) {
                行.children.forEach(单元格 => {
                  let 单元格文本 = '';
                  
                  if (单元格.children && Array.isArray(单元格.children)) {
                    单元格.children.forEach(段落 => {
                      if (段落.children && Array.isArray(段落.children)) {
                        段落.children.forEach(文本元素 => {
                          if (文本元素.text) {
                            单元格文本 += 文本元素.text;
                          }
                        });
                      }
                      单元格文本 += '\n';
                    });
                  }
                  
                  行数据.push(单元格文本.trim());
                });
              }
              
              表格数据.push(行数据);
            });
          }
          
          表格列表.push(表格数据);
        }
      });
    }
  });
  
  return 表格列表;
}

/**
 * 保护文档
 * @param {Object} 文档 - docx文档实例
 * @param {string} 密码 - 保护密码
 * @param {Object} 保护选项 - 保护选项
 * @returns {Object} 受保护的文档
 */
function 保护文档(文档, 密码, 保护选项 = {}) {
  验证docx库();
  
  // 设置文档保护
  if (!文档.settings) {
    文档.settings = {};
  }
  
  // 注意：docx库的当前版本可能有限制，以下是基本实现
  文档.settings.documentProtection = {
    edit: 保护选项.编辑类型 || 'readOnly',
    enforced: true,
   cryptProviderType: 'rsaAES',
    cryptAlgorithmClass: 'hash',
    cryptAlgorithmType: 'typeAny',
    cryptAlgorithmSid: 14, // SHA-1
    spinCount: 100000,
    saltValue: Math.random().toString(36).substring(2, 18),
    hashValue: Math.random().toString(36).substring(2, 18)
  };
  
  return 文档;
}

/**
 * 移除文档保护
 * @param {Object} 文档 - docx文档实例
 * @returns {Object} 未受保护的文档
 */
function 移除保护(文档) {
  验证docx库();
  
  if (文档.settings && 文档.settings.documentProtection) {
    delete 文档.settings.documentProtection;
  }
  
  return 文档;
}

/**
 * 压缩文档（尝试移除不必要的元素）
 * @param {Object} 文档 - docx文档实例
 * @returns {Object} 压缩后的文档
 */
function 压缩文档(文档) {
  验证docx库();
  
  // 基本压缩：移除空段落和不必要的格式
  const 节列表 = 获取文档节(文档);
  
  节列表.forEach(节 => {
    if (节.children && Array.isArray(节.children)) {
      // 过滤掉空段落
      节.children = 节.children.filter(元素 => {
        if (元素 instanceof docx.Paragraph) {
          // 检查段落是否为空
          if (!元素.children || 元素.children.length === 0) {
            return false;
          }
          
          // 检查是否只包含空文本
          const 非空文本 = 元素.children.some(文本元素 => 
            文本元素 instanceof docx.TextRun && 
            文本元素.text && 
            文本元素.text.trim() !== ''
          );
          
          return 非空文本;
        }
        return true;
      });
    }
  });
  
  return 文档;
}

/**
 * 比较两个文档的差异
 * @param {Object} 文档1 - 第一个文档
 * @param {Object} 文档2 - 第二个文档
 * @returns {Object} 差异信息
 */
function 比较文档(文档1, 文档2) {
  验证docx库();
  
  const 文本1 = 获取文档文本(文档1);
  const 文本2 = 获取文档文本(文档2);
  
  const 差异 = {
    文本差异: 文本1 !== 文本2,
    文本长度差异: 文本1.length - 文本2.length,
    文档1文本长度: 文本1.length,
    文档2文本长度: 文本2.length
  };
  
  // 简单的差异检测
  if (文本1 !== 文本2) {
    // 查找第一个差异位置
    const 最小长度 = Math.min(文本1.length, 文本2.length);
    let 差异位置 = 0;
    
    for (let i = 0; i < 最小长度; i++) {
      if (文本1[i] !== 文本2[i]) {
        差异位置 = i;
        break;
      }
    }
    
    差异.第一个差异位置 = 差异位置;
    // 获取差异上下文
    const 上下文长度 = 20;
    差异.文档1上下文 = 文本1.substring(
      Math.max(0, 差异位置 - 上下文长度),
      Math.min(文本1.length, 差异位置 + 上下文长度)
    );
    差异.文档2上下文 = 文本2.substring(
      Math.max(0, 差异位置 - 上下文长度),
      Math.min(文本2.length, 差异位置 + 上下文长度)
    );
  }
  
  return 差异;
}

/**
 * 创建邮件合并功能
 * @param {Object} 文档 - 模板文档
 * @param {Array} 数据 - 合并数据数组
 * @param {Object} 选项 - 合并选项
 * @returns {Array} 合并后的文档数组
 */
function 创建邮件合并(文档, 数据, 选项 = {}) {
  验证docx库();
  
  if (!Array.isArray(数据)) {
    throw new Error('合并数据必须是数组');
  }
  
  const 合并文档列表 = [];
  const 占位符模式 = 选项.占位符模式 || /\{([^{}]+)\}/g;
  
  数据.forEach((记录, 索引) => {
    // 创建文档副本
    const 文档副本 = JSON.parse(JSON.stringify(文档));
    
    // 替换占位符
    const 文本内容 = 获取文档文本(文档);
    let 替换后文本 = 文本内容.replace(占位符模式, (匹配, 键) => {
      return 记录[键.trim()] !== undefined ? 记录[键.trim()] : 匹配;
    });
    
    // 这里简化处理，实际应用中需要更复杂的替换逻辑
    合并文档列表.push({
      索引,
      数据: 记录,
      文档: 文档副本
    });
  });
  
  return 合并文档列表;
}

/**
 * 导出文档为HTML格式
 * @param {Object} 文档 - docx文档实例
 * @returns {string} HTML内容
 */
function 导出为HTML(文档) {
  验证docx库();
  
  const 文本内容 = 获取文档文本(文档);
  // 简单的HTML转换
  let html = '<!DOCTYPE html>\n<html>\n<head>\n';
  html += '<meta charset="UTF-8">\n';
  html += '<title>Word文档HTML导出</title>\n';
  html += '<style>body { font-family: Arial, sans-serif; line-height: 1.6; }</style>\n';
  html += '</head>\n<body>\n';
  
  // 将文本按行分割并转换为HTML段落
  const 行 = 文本内容.split('\n');
  行.forEach(行文本 => {
    if (行文本.trim()) {
      html += `<p>${行文本}</p>\n`;
    }
  });
  
  html += '</body>\n</html>';
  
  return html;
}

/**
 * 导出文档为Markdown格式
 * @param {Object} 文档 - docx文档实例
 * @returns {string} Markdown内容
 */
function 导出为Markdown(文档) {
  验证docx库();
  
  const 文本内容 = 获取文档文本(文档);
  // 简单的Markdown转换
  let markdown = '';
  
  // 将文本按行分割并转换为Markdown格式
  const 行 = 文本内容.split('\n');
  行.forEach(行文本 => {
    if (行文本.trim()) {
      markdown += `${行文本}\n`;
    } else {
      markdown += '\n';
    }
  });
  
  return markdown.trim();
}

/**
 * 应用模板到文档
 * @param {Object} 文档 - 目标文档
 * @param {Object} 模板 - 模板文档或模板配置
 * @returns {Object} 应用模板后的文档
 */
function 应用模板(文档, 模板) {
  验证docx库();
  
  // 如果模板是文档实例
  if (模板.sections && Array.isArray(模板.sections)) {
    // 应用模板的样式和结构
    if (模板.styles) {
      文档.styles = { ...模板.styles };
    }
    
    // 应用第一个节的属性作为模板
    if (模板.sections[0] && 模板.sections[0].properties) {
      const 节列表 = 获取文档节(文档);
      节列表.forEach(节 => {
        if (!节.properties) {
          节.properties = {};
        }
        Object.assign(节.properties, { ...模板.sections[0].properties });
      });
    }
  }
  // 如果模板是配置对象
  else if (typeof 模板 === 'object') {
    if (模板.styles) {
      文档.styles = { ...模板.styles };
    }
    
    if (模板.pageProperties) {
      const 节列表 = 获取文档节(文档);
      节列表.forEach(节 => {
        if (!节.properties) {
          节.properties = {};
        }
        Object.assign(节.properties, { ...模板.pageProperties });
      });
    }
  }
  
  return 文档;
}

/**
 * 创建新的Word文档
 * @param {Object} 文档选项 - 文档配置选项
 * @returns {Object} 文档实例
 */
function 创建文档(文档选项 = {}) {
  验证docx库();
  
  return new docx.Document({
    sections: 文档选项.节 || [],
    styles: 文档选项.样式 || {},
    footnotes: 文档选项.脚注 || [],
    endnotes: 文档选项.尾注 || [],
    ...文档选项
  });
}

/**
 * 保存文档到文件
 * @param {Object} 文档 - docx文档实例
 * @param {string} 文件路径 - 保存路径
 * @returns {Promise<void>}
 */
async function 保存文档到文件(文档, 文件路径) {
  验证docx库();
  
  try {
    const buffer = await docx.Packer.toBuffer(文档);
    await fs.promises.writeFile(file_path, buffer);
    return 文件路径;
  } catch (错误) {
    throw new Error(`保存文档失败: ${错误.message}`);
  }
}

/**
 * 将文档转换为Buffer
 * @param {Object} 文档 - docx文档实例
 * @returns {Promise<Buffer>}
 */
async function 转换为Buffer(文档) {
  验证docx库();
  
  try {
    return await docx.Packer.toBuffer(文档);
  } catch (错误) {
    throw new Error(`转换文档为Buffer失败: ${错误.message}`);
  }
}

/**
 * 创建文档节
 * @param {Object} 节选项 - 节配置选项
 * @returns {Object} 节实例
 */
function 创建节(节选项 = {}) {
  验证docx库();
  
  return new docx.Section({
    properties: {
      pageSize: 节选项.页面尺寸 || {},
      pageMargin: 节选项.页面边距 || {},
      orientation: 节选项.方向 || 'portrait',
      ...节选项.属性 || {}
    },
    children: 节选项.子元素 || [],
    ...节选项
  });
}

/**
 * 创建文本段落
 * @param {string|Array} 文本内容 - 文本内容或文本元素数组
 * @param {Object} 段落选项 - 段落样式选项
 * @returns {Object} 段落实例
 */
function 创建段落(文本内容, 段落选项 = {}) {
  验证docx库();
  
  let 段落内容;
  
  if (typeof 文本内容 === 'string') {
    段落内容 = [创建文本(文本内容)];
  } else if (Array.isArray(文本内容)) {
    段落内容 = 文本内容;
  } else {
    段落内容 = [文本内容];
  }
  
  return new docx.Paragraph({
    children: 段落内容,
    style: 段落选项.样式 || '',
    alignment: 段落选项.对齐方式 || 'left',
    spacing: 段落选项.间距 || {},
    indent: 段落选项.缩进 || {},
    bullet: 段落选项.项目符号 || null,
    numbering: 段落选项.编号 || null,
    border: 段落选项.边框 || {},
    ...段落选项
  });
}

/**
 * 创建纯文本
 * @param {string} 文本 - 文本内容
 * @param {Object} 文本选项 - 文本样式选项
 * @returns {Object} 文本实例
 */
function 创建文本(文本, 文本选项 = {}) {
  验证docx库();
  
  return new docx.TextRun({
    text: 文本,
    bold: 文本选项.粗体 || false,
    italics: 文本选项.斜体 || false,
    underline: 文本选项.下划线 || false,
    color: 文本选项.颜色 || '000000',
    size: 文本选项.字号 || 24,
    highlight: 文本选项.高亮 || undefined,
    font: 文本选项.字体 || undefined,
    ...文本选项
  });
}

/**
 * 创建标题
 * @param {string} 标题文本 - 标题文本
 * @param {number} 级别 - 标题级别(1-9)
 * @param {Object} 标题选项 - 标题样式选项
 * @returns {Object} 标题段落实例
 */
function 创建标题(标题文本, 级别 = 1, 标题选项 = {}) {
  验证docx库();
  
  const 标题样式 = `Heading${Math.min(9, Math.max(1, 级别))}`;
  
  return 创建段落(标题文本, {
    style: 标题样式,
    alignment: 'left',
    ...标题选项
  });
}

/**
 * 创建表格
 * @param {Array} 表格数据 - 二维数组表示的表格数据
 * @param {Object} 表格选项 - 表格样式选项
 * @returns {Object} 表格实例
 */
function 创建表格(表格数据, 表格选项 = {}) {
  验证docx库();
  
  const 行 = 表格数据.map((行数据, 行索引) => {
    const 单元格 = 行数据.map((单元格数据, 列索引) => {
      const 单元格选项 = 表格选项.单元格样式 && 表格选项.单元格样式[行索引] && 表格选项.单元格样式[行索引][列索引] 
        ? 表格选项.单元格样式[行索引][列索引] 
        : {};
      
      return 创建表格单元格(单元格数据, 单元格选项);
    });
    
    return new docx.TableRow({
      children: 单元格,
      ...(表格选项.行样式 && 表格选项.行样式[行索引] ? 表格选项.行样式[行索引] : {})
    });
  });
  
  return new docx.Table({
    rows: 行,
    width: {
      size: 表格选项.宽度 || 100,
      type: 'percent'
    },
    style: 表格选项.样式 || 'Table Grid',
    ...表格选项
  });
}

/**
 * 创建表格单元格
 * @param {string|Array} 内容 - 单元格内容
 * @param {Object} 单元格选项 - 单元格样式选项
 * @returns {Object} 表格单元格实例
 */
function 创建表格单元格(内容, 单元格选项 = {}) {
  验证docx库();
  
  let 单元格内容;
  if (typeof 内容 === 'string') {
    单元格内容 = [创建段落(内容)];
  } else if (Array.isArray(内容)) {
    单元格内容 = 内容;
  } else {
    单元格内容 = [内容];
  }
  
  return new docx.TableCell({
    children: 单元格内容,
    borders: 单元格选项.边框 || {},
    shading: 单元格选项.底纹 || {},
    width: 单元格选项.宽度,
    ...单元格选项
  });
}

/**
 * 创建图片
 * @param {string|Buffer} 图片数据 - 图片路径或Buffer
 * @param {Object} 图片选项 - 图片样式选项
 * @returns {Object} 图片段落实例
 */
function 创建图片(图片数据, 图片选项 = {}) {
  验证docx库();
  
  let 图像数据;
  
  if (typeof 图片数据 === 'string' && fs.existsSync(图片数据)) {
    图像数据 = fs.readFileSync(图片数据);
  } else if (Buffer.isBuffer(图片数据)) {
    图像数据 = 图片数据;
  } else {
    throw new Error('图片数据必须是文件路径或Buffer');
  }
  
  const 图像 = new docx.ImageRun({
    data: 图像数据,
    transformation: {
      width: 图片选项.宽度 || 500,
      height: 图片选项.高度 || 300,
    },
    alt: 图片选项.替代文本 || '',
    ...图片选项
  });
  
  return 创建段落([图像], {
    alignment: 图片选项.对齐方式 || 'center',
    ...图片选项.段落选项
  });
}

/**
 * 创建超链接
 * @param {string} 链接文本 - 链接显示文本
 * @param {string} 链接URL - 链接目标URL
 * @param {Object} 链接选项 - 链接样式选项
 * @returns {Object} 超链接文本实例
 */
function 创建超链接(链接文本, 链接URL, 链接选项 = {}) {
  验证docx库();
  
  return new docx.ExternalHyperlink({
    children: [创建文本(链接文本, {
      color: '0000FF',
      underline: true,
      ...链接选项
    })],
    link: 链接URL
  });
}

/**
 * 创建书签
 * @param {string} 书签名称 - 书签唯一标识符
 * @param {string|Object} 内容 - 书签内容
 * @param {Object} 书签选项 - 书签选项
 * @returns {Object} 书签实例
 */
function 创建书签(书签名称, 内容, 书签选项 = {}) {
  验证docx库();
  
  const 书签内容 = typeof 内容 === 'string' ? 创建文本(内容) : 内容;
  
  return new docx.Bookmark({
    id: 书签名称,
    children: [书签内容],
    ...书签选项
  });
}

/**
 * 创建目录
 * @param {Object} 目录选项 - 目录样式选项
 * @returns {Object} 目录段落实例
 */
function 创建目录(目录选项 = {}) {
  验证docx库();
  
  const 目录标题 = 创建标题('目录', 1, {
    alignment: 'center',
    ...目录选项.标题样式
  });
  
  const 目录段落 = new docx.Paragraph({
    children: [new docx.TableOfContents({
      title: '',
      hyperlink: 目录选项.超链接 || true,
      headingStyleRange: {
        start: 目录选项.起始级别 || 1,
        end: 目录选项.结束级别 || 3
      },
      ...目录选项
    })],
    ...目录选项.段落样式
  });
  
  return [目录标题, 目录段落];
}

/**
 * 创建项目符号列表
 * @param {Array} 列表项 - 列表项数组
 * @param {Object} 列表选项 - 列表样式选项
 * @returns {Array} 列表段落数组
 */
function 创建项目符号列表(列表项, 列表选项 = {}) {
  验证docx库();
  
  return 列表项.map((项, 索引) => {
    return 创建段落(项, {
      bullet: {
        level: 列表选项.级别 || 0
      },
      ...列表选项,
      style: 列表选项.样式 || ''
    });
  });
}

/**
 * 创建编号列表
 * @param {Array} 列表项 - 列表项数组
 * @param {Object} 列表选项 - 列表样式选项
 * @returns {Array} 列表段落数组
 */
function 创建编号列表(列表项, 列表选项 = {}) {
  验证docx库();
  
  // 创建编号定义
  const 编号定义 = new docx.Numbering({
    config: [
      {
        reference: 'numbering',
        levels: [
          {
            level: 0,
            format: 'decimal',
            text: '%1.',
            alignment: 'left',
            style: {
              paragraph: {
                indent: {
                  left: 720,
                  hanging: 360
                }
              }
            }
          }
        ]
      }
    ]
  });
  
  return 列表项.map((项, 索引) => {
    return 创建段落(项, {
      numbering: {
        reference: 'numbering',
        level: 列表选项.级别 || 0
      },
      ...列表选项
    });
  });
}

/**
 * 创建页眉
 * @param {Array|Object} 页眉内容 - 页眉内容
 * @param {Object} 页眉选项 - 页眉样式选项
 * @returns {Object} 页眉实例
 */
function 创建页眉(页眉内容, 页眉选项 = {}) {
  验证docx库();
  
  return new docx.Header({
    children: Array.isArray(页眉内容) ? 页眉内容 : [页眉内容],
    ...页眉选项
  });
}

/**
 * 创建页脚
 * @param {Array|Object} 页脚内容 - 页脚内容
 * @param {Object} 页脚选项 - 页脚样式选项
 * @returns {Object} 页脚实例
 */
function 创建页脚(页脚内容, 页脚选项 = {}) {
  验证docx库();
  
  return new docx.Footer({
    children: Array.isArray(页脚内容) ? 页脚内容 : [页眉内容],
    ...页脚选项
  });
}

/**
 * 创建页码
 * @param {Object} 页码选项 - 页码样式选项
 * @returns {Object} 页码文本实例
 */
function 创建页码(页码选项 = {}) {
  验证docx库();
  
  return new docx.PageNumber({
    format: 页码选项.格式 || '%1',
    ...页码选项
  });
}

/**
 * 创建文本框
 * @param {Array|Object} 文本框内容 - 文本框内容
 * @param {Object} 文本框选项 - 文本框样式选项
 * @returns {Object} 文本框实例
 */
function 创建文本框(文本框内容, 文本框选项 = {}) {
  验证docx库();
  
  return new docx.Textbox({
    children: Array.isArray(文本框内容) ? 文本框内容 : [文本框内容],
    width: 文本框选项.宽度 || {
      size: 400,
      type: 'dxa'
    },
    height: 文本框选项.高度 || {
      size: 200,
      type: 'dxa'
    },
    ...文本框选项
  });
}

/**
 * 创建分隔线
 * @param {Object} 分隔线选项 - 分隔线样式选项
 * @returns {Object} 分隔线段落实例
 */
function 创建分隔线(分隔线选项 = {}) {
  验证docx库();
  
  return new docx.Paragraph({
    children: [new docx.HorizontalRule({
      color: 分隔线选项.颜色 || '000000',
      ...分隔线选项
    })],
    ...分隔线选项.段落选项
  });
}

/**
 * 创建样式定义
 * @param {string} 样式名称 - 样式名称
 * @param {Object} 样式属性 - 样式属性
 * @returns {Object} 样式定义实例
 */
function 创建样式(样式名称, 样式属性 = {}) {
  验证docx库();
  
  return new docx.Style({
    id: 样式名称,
    name: 样式名称,
    type: 样式属性.类型 || 'paragraph',
    paragraph: 样式属性.段落样式 || {},
    character: 样式属性.字符样式 || {},
    ...样式属性
  });
}

/**
 * 创建样式集合
 * @param {Array} 样式数组 - 样式定义数组
 * @returns {Object} 样式集合实例
 */
function 创建样式集合(样式数组 = []) {
  验证docx库();
  
  return new docx.Styles({
    defaults: {},
    styles: 样式数组
  });
}

/**
 * 创建页面尺寸
 * @param {number} 宽度 - 页面宽度
 * @param {number} 高度 - 页面高度
 * @param {string} 单位 - 单位（dxa或cm）
 * @returns {Object} 页面尺寸对象
 */
function 创建页面尺寸(宽度 = 11906, 高度 = 16838, 单位 = 'dxa') {
  return {
    width: {
      size: 宽度,
      type: 单位
    },
    height: {
      size: 高度,
      type: 单位
    }
  };
}

/**
 * 创建页面边距
 * @param {number} 顶部 - 顶部边距
 * @param {number} 右侧 - 右侧边距
 * @param {number} 底部 - 底部边距
 * @param {number} 左侧 - 左侧边距
 * @param {string} 单位 - 单位（dxa或cm）
 * @returns {Object} 页面边距对象
 */
function 创建页面边距(顶部 = 1440, 右侧 = 1440, 底部 = 1440, 左侧 = 1440, 单位 = 'dxa') {
  return {
    top: {
      size: 顶部,
      type: 单位
    },
    right: {
      size: 右侧,
      type: 单位
    },
    bottom: {
      size: 底部,
      type: 单位
    },
    left: {
      size: 左侧,
      type: 单位
    }
  };
}

/**
 * 创建复杂文档
 * @param {Object} 文档配置 - 文档配置对象
 * @returns {Object} 文档实例
 */
function 创建复杂文档(文档配置 = {}) {
  验证docx库();
  
  const 文档 = 创建文档();
  const 节 = 创建节();
  
  // 添加目录
  if (文档配置.包含目录) {
    const 目录 = 创建目录(文档配置.目录选项);
    目录.forEach(项 => 节.addItem(项));
    // 添加分页符
    节.addItem(new docx.Paragraph({
      pageBreak: true
    }));
  }
  
  // 添加标题
  if (文档配置.标题) {
    节.addItem(创建标题(文档配置.标题, 1, { 
      margin: {
        bottom: 200
      },
      ...文档配置.标题样式
    }));
  }
  
  // 添加副标题
  if (文档配置.副标题) {
    节.addItem(创建标题(文档配置.副标题, 2, { 
      margin: {
        bottom: 150
      },
      ...文档配置.副标题样式
    }));
  }
  
  // 添加作者信息
  if (文档配置.作者) {
    节.addItem(创建段落(`作者: ${文档配置.作者}`, {
      margin: {
        bottom: 100
      },
      fontSize: 20,
      color: '666666',
      ...文档配置.作者样式
    }));
  }
  
  // 添加日期
  if (文档配置.日期) {
    节.addItem(创建段落(`日期: ${文档配置.日期}`, {
      margin: {
        bottom: 200
      },
      fontSize: 20,
      color: '666666',
      ...文档配置.日期样式
    }));
  }
  
  // 添加摘要
  if (文档配置.摘要) {
    节.addItem(创建标题('摘要', 2, { 
      margin: {
        top: 150,
        bottom: 100
      }
    }));
    节.addItem(创建段落(文档配置.摘要, {
      margin: {
        bottom: 150
      },
      ...文档配置.摘要样式
    }));
  }
  
  // 添加正文段落
  if (文档配置.段落 && Array.isArray(文档配置.段落)) {
    文档配置.段落.forEach((段落, 索引) => {
      节.addItem(创建段落(段落, {
        margin: {
          bottom: 100
        },
        ...文档配置.段落样式
      }));
    });
  }
  
  // 添加表格
  if (文档配置.表格 && 文档配置.表格数据) {
    节.addItem(创建标题(文档配置.表格标题 || '表格', 3, { 
      margin: {
        top: 150,
        bottom: 100
      }
    }));
    节.addItem(创建表格(文档配置.表格数据, {
      margin: {
        bottom: 150
      },
      ...文档配置.表格样式
    }));
  }
  
  // 添加图片
  if (文档配置.图片) {
    节.addItem(创建标题(文档配置.图片标题 || '图片', 3, { 
      margin: {
        top: 150,
        bottom: 100
      }
    }));
    节.addItem(创建图片(文档配置.图片, {
      margin: {
        bottom: 150
      },
      ...文档配置.图片样式
    }));
  }
  
  // 添加列表
  if (文档配置.列表项 && Array.isArray(文档配置.列表项)) {
    节.addItem(创建标题(文档配置.列表标题 || '列表', 3, { 
      margin: {
        top: 150,
        bottom: 100
      }
    }));
    
    const 列表 = 文档配置.列表类型 === 'numbered' 
      ? 创建编号列表(文档配置.列表项, 文档配置.列表样式)
      : 创建项目符号列表(文档配置.列表项, 文档配置.列表样式);
    
    列表.forEach(项 => 节.addItem(项));
    
    // 添加底部间距
    节.addItem(创建段落('', {
      margin: {
        bottom: 100
      }
    }));
  }
  
  // 设置页眉页脚
  if (文档配置.页眉) {
    节.properties.header = 创建页眉(文档配置.页眉, 文档配置.页眉样式);
  }
  
  if (文档配置.页脚) {
    节.properties.footer = 创建页脚(文档配置.页脚, 文档配置.页脚样式);
  }
  
  // 设置页面属性
  if (文档配置.页面尺寸) {
    节.properties.pageSize = 文档配置.页面尺寸;
  }
  
  if (文档配置.页面边距) {
    节.properties.pageMargin = 文档配置.页面边距;
  }
  
  if (文档配置.页面方向) {
    节.properties.orientation = 文档配置.页面方向;
  }
  
  // 添加节到文档
  文档.addSection(节);
  
  return 文档;
}

// 导出模块
module.exports = {
  // 核心功能
  创建文档,
  保存文档到文件,
  转换为Buffer,
  创建复杂文档,
  
  // 文档结构
  创建节,
  创建段落,
  创建标题,
  
  // 文本元素
  创建文本,
  创建超链接,
  创建书签,
  
  // 表格相关
  创建表格,
  创建表格单元格,
  
  // 媒体元素
  创建图片,
  创建分隔线,
  
  // 列表
  创建项目符号列表,
  创建编号列表,
  
  // 目录和页码
  创建目录,
  创建页码,
  
  // 页眉页脚
  创建页眉,
  创建页脚,
  
  // 样式系统
  创建样式,
  创建样式集合,
  
  // 布局设置
  创建页面尺寸,
  创建页面边距,
  
  // 其他元素
  创建文本框,
  
  // 文档读取与修改功能
  读取Word文档,
  从Buffer加载文档,
  获取文档节,
  获取文档文本,
  搜索文本,
  替换文本,
  添加水印,
  设置文档属性,
  获取文档属性,
  添加页脚页码,
  合并文档,
  提取图片,
  提取表格数据,
  保护文档,
  移除保护,
  压缩文档,
  比较文档,
  
  // 高级功能
  创建邮件合并,
  导出为HTML,
  导出为Markdown,
  应用模板,
  
  // 常量
  页面方向: {
    纵向: 'portrait',
    横向: 'landscape'
  },
  对齐方式: {
    左对齐: 'left',
    右对齐: 'right',
    居中: 'center',
    两端对齐: 'both'
  },
  列表类型: {
    项目符号: 'bulleted',
    编号: 'numbered'
  },
  页面尺寸预设: {
    A4: 创建页面尺寸(11906, 16838),
    A3: 创建页面尺寸(16838, 23811),
    A5: 创建页面尺寸(8419, 11906),
    信纸: 创建页面尺寸(12240, 15840),
    法律纸: 创建页面尺寸(12240, 20160)
  },
  
  // 获取原始库
  获取原始docx: () => docx,
  验证docx库
};